export class Register {
    private A: number;
    private X: number;
    private Y: number;
    private SP: number;
    private PC: number;


    getA() {
        return this.A;
    }

    getX() {
        return this.X;
    }

    getY() {
        return this.Y;
    }

    setA(value: number): void {
        this.A = 0xff & value;
    }
    setX(value: number): void {
        this.X = 0xff & value;
    }
    setY(value: number): void {
        this.Y = 0xff & value;
    }
    setSP(value: number): void {
        this.SP = value & 0xff;
    }

    getSP(): number {
        return this.SP;
    }

    incSP(): boolean {
        if (this.SP > 0x01ff) {
            return false;
        }
        this.SP++;
        return true;
    }

    decSP(): boolean {
        if (this.SP < 0x0100) {
            return false;
        }
        this.SP--;
        return true;
    }



    STATUS = {
        flag: 0b00000000,
        getFlag(): number {
            return this.flag;
        },
        setFlag(value: number): void {
            this.flag = value & 0xff;
        },
        setNZ(value: number): void {
            // 是否为零
            if (value === 0) {
                this.setZ(true);
            } else {
                this.setZ(false);
            }

            //是否为负数
            if (value & 0x80) {
                this.setN(true);
            } else {
                this.setN(false);
            }
        },
        setNZC(value: number): void {

            //进位判断
            if (value >= 0x100) {
                this.setC(true);
            } else {
                this.setC(false);
            }
            this.setNZ(value);

        },
        setC(value: boolean): void {
            if (value) {
                this.FLAG = this.FLAG | 0b00000001;
            } else {
                this.FLAG = this.FLAG & ~0b00000001;
            }

        },
        getC(): number {
            if ((this.FLAG & 0b00000001) != 0) {
                return 1;
            }
            return 0;
        },
        setZ(value: boolean): void {
            if (value) {
                this.FLAG = this.FLAG | 0b00000010;
            } else {
                this.FLAG = this.FLAG & ~0b00000010;
            }
        },
        getZ(): boolean {
            return (this.FLAG & 0b00000010) != 0;
        },
        setI(value: boolean): void {
            if (value) {
                this.FLAG = this.FLAG | 0b00000100;
            } else {
                this.FLAG = this.FLAG & ~0b00000100;
            }
        },
        getI(): boolean {
            return (this.FLAG & 0b00000100) != 0;
        },
        setD(value: boolean): void {
            if (value) {
                this.FLAG = this.FLAG | 0b00001000;
            } else {
                this.FLAG = this.FLAG & ~0b00001000;
            }
        },
        getD(): boolean {
            return (this.FLAG & 0b00001000) != 0;
        },
        setB(value: boolean): void {
            if (value) {
                this.FLAG = this.FLAG | 0b00010000;
            } else {
                this.FLAG = this.FLAG & ~0b00010000;
            }
        },
        getB(): boolean {
            return (this.FLAG & 0b00010000) != 0;
        },
        setV(value: boolean): void {
            if (value) {
                this.FLAG = this.FLAG | 0b01000000;
            } else {
                this.FLAG = this.FLAG & ~0b01000000;
            }
        },
        getV(): boolean {
            return (this.FLAG & 0b01000000) != 0;
        },

        setN(value: boolean): void {
            if (value) {
                this.FLAG = this.FLAG | 0b10000000;
            } else {
                this.FLAG = this.FLAG & ~0b10000000;
            }
        },
        getN(): boolean {
            return (this.FLAG & 0b10000000) != 0;
        }
    }
    reset() {
        this.A = 0;
        this.X = 0;
        this.Y = 0;
        this.SP = 0x01ff;
        this.PC = 0xfffc;
    }
    push(): boolean {
        if (this.SP === 0x0100) {
            return false;
        }

        this.SP--;
        return true;
    }

    pop(): void {
        if (this.SP === 0x01ff) {
            return;
        }
        this.SP++;
    }
    incPC() {
        this.PC++;
    }
    decPC() {
        this.PC--;
    }
    getPC() {
        return this.PC;
    }
    nextPC() {
        return this.PC++;
    }
    setPC(addr: number): void {
        this.PC = 0xffff & addr;
    }

    constructor() {
        this.reset();
    }

}